package gamebackend;

import java.util.Random;

/**
 * Directs its child to fly to random positions. Once the child reaches a target
 * position it is directed to a new target position.A minimum and maximum
 * difference between the current child position and new target can be set.
 * 
 * @author Jonathan Caddey
 */
public class RestlessFlier extends AbstractFlier {

	private final Random my_random;
	private final double my_minX;
	private final double my_maxX;
	private final double my_minChange;
	private final double my_maxChange;
	
	public RestlessFlier(final Flier the_child, final Random the_random,
			final double the_minChange, final double the_maxChange,
			final double the_minX, final double the_maxX) {
		super(the_child);
		my_random = the_random;
		my_minX = the_minX;
		my_maxX = the_maxX;
		my_minChange = the_minChange;
		my_maxChange = the_maxChange;

		getNewTarget();
	}
	
	public RestlessFlier(final Flier the_child, final Random the_random,
			final double the_minX, final double the_maxX) {
		this(the_child, the_random, the_minX, the_maxX, the_minX, the_maxX);
	}
	
	
	
	@Override
	public void step(final double the_yChange) {
		super.step(the_yChange);
		if (getChild().isAtTarget()) {
			getNewTarget();
		}
	}
	
	private final void getNewTarget() {
		// construct 2 areas--left and right--where the ship can randomly move to
		// while obeying the boundaries of the screen and the min/max change range.
		// Below are the variables illustrated.  Dashed areas are ineligable for the new target.
		//
		//
		//  my_minX     left start                          x        rightStart                    my_maxX
		//   |------------|      leftLength      |---------/\---------|   rightLength      |----------|
		
		
		final double x = getChild().getPosition();
		final double leftStart = Math.max(my_minX, x - my_maxChange);
		final double leftLength = Math.max(0, x - my_minChange - leftStart);
		final double rightStart = Math.min(x + my_minChange, my_maxX);
		final double rightLength = Math.min(my_maxX - rightStart, x + my_maxChange - rightStart);
		final double random = my_random.nextDouble() * (leftLength + rightLength);
		final double target;
		if (leftLength + rightLength == 0) {
			final boolean canLeft = x - my_minChange >= my_minX;
			final boolean canRight = x + my_minChange <= my_maxX;
			if (canLeft && canRight) {
				target = x + my_minChange * (my_random.nextInt(2) * 2 - 1); 
			} else if (canLeft) {
				target = x - my_minChange;
			} else if (canRight) {
				target = x + my_minChange;
			} else {
				target = my_minX + my_random.nextDouble() * (my_maxX - my_minX);
			}
			
		} else if (random < leftLength) {
			target = leftStart + random;
		} else {
			target = rightStart + random - leftLength;
		}
		getChild().setTarget(target);
	}
}
